home *** CD-ROM | disk | FTP | other *** search
/ PC Media 20 / PC MEDIA CD20.iso / share / prog / cursoasm / cap3.msg < prev    next >
Text File  |  1993-06-17  |  10KB  |  222 lines

  1.                    INTRODUCCION AL ASM: LA INSTRUCCION MOV (I)
  2.                    ===========================================
  3.  
  4.    La operación más básica que el uP es capaz de realizar es el movimiento de
  5. datos (números) de un lugar a otro. Puede moverlos de un registro a otro, de
  6. un registro a la memoria o de la memoria a un registro.
  7.  
  8.    La instrucción en lenguaje ensamblador que representa esta operación se
  9. denomina 'MOV', del inglés 'move', y puede traducirse en muchos códigos de
  10. operación distintos en función del origen y el destino del dato. La instrucción
  11. MOV tiene dos operandos, que van después del 'mov' dejando uno o varios separa-
  12. dores entre el 'MOV' y el primer operando (diciendo separadores nos referire-
  13. mos siempre a los espacios - carácter 32d o 20h - y a los tabuladores - carác-
  14. ter 09) y separados por una coma y/o varios separadores. La sintáxis es la
  15. siguiente:
  16.  
  17.         MOV destino,origen
  18.  
  19.    En esta instrucción 'origen' significa el lugar de donde el uP recoge el
  20. dato a mover y 'destino' el lugar donde lo escribe después. Estos operandos
  21. pueden ser de muchas formas, y en función de la forma de estos se habla del
  22. 'modo de direccionamiento', que es el modo en como se accede al destino o al
  23. origen. Podríamos dar una larga y tediosa lista de los nombres de todos los
  24. modos de direccionamiento, pero lo que haremos será ir viendo ejemplos fácil-
  25. mente asimilables, de forma que luego quien quiera pueda aprenderse los nombres
  26. de los distintos modos de direccionamiento.
  27.  
  28.    Uno de los usos más sencillos es el de mover un dato de un registro a otro.
  29. Por ejemplo, para mover el dato del registro BX al registro AX escribiríamos:
  30.  
  31.         MOV AX,BX
  32.  
  33.    El contenido anterior del registro AX se pierde, de manera que el valor del
  34. BX 'pisa' lo que hubiera en el AX. Después de ejecutarse esta instrucción, los
  35. registros BX y AX contendrán el mismo valor, el contenido anterior del BX.
  36.  
  37.    De la misma forma, podemos comprender las siguientes instrucciones:
  38.  
  39.         MOV AX,DS
  40.         MOV ES,AX
  41.         MOV DX,AX
  42.         ...
  43.  
  44.    Hacemos aquí un pequeño inciso para explicar cómo se añaden los comentarios
  45. a los listados en ASM: cuando el ensamblador encuentra un punto y coma (carác-
  46. ter ';'), ignora todos los caracteres hasta que encuentra el final de la línea
  47. actual. Por tanto, las instrucciones anteriores se pueden comentar:
  48.  
  49.         MOV AX,DS    ; Carga AX con el valor del DS
  50.         MOV ES,AX    ; ES = AX
  51.         MOV DX,BX    ; DX <- BX
  52.  
  53.    Esta convención para los comentarios la aceptan los ensambladores como el
  54. MASM o el TASM, pero también lo acepta el DEBUG del MS-DOS (más adelante
  55. veremos cómo usarlo).
  56.  
  57.    Retomemos los usos de la instrucción MOV. Otra de las posibilidades es
  58. cargar en un registro directamente un valor. Por ejemplo, podemos inicializar
  59. los registros AX, BX, CX y DX a 1,2,3 y 4 respectivamente con las siguientes
  60. instrucciones:
  61.  
  62.         MOV AX,1
  63.         MOV BX,2
  64.         MOV CX,3
  65.         MOV DX,4
  66.  
  67.    Un punto que me gustaría destacar respecto al uso 'MOV reg,valor' es que
  68. los registros de segmento no se pueden cargar directamente. Es decir, no
  69. existe código de operación para la instrucción
  70.  
  71.         MOV DS,0040h
  72.  
  73.    Sino que hay que hacerlo necesariamente por medio de otro registro:
  74.  
  75.         MOV AX,0040h
  76.         MOV DS,AX
  77.  
  78.    Otro aspecto que querría comentar respecto a la instrucción 'MOV': el
  79. código de operación de las instrucciones de transferencia entre registros in-
  80. corpora algunos campos que especifican de qué registro a qué registro se mueve
  81. el dato. Pero en estas últimas instrucciones, el dato que se quiere cargar en
  82. el registro va con el propio código de operación. Es decir, el 8086 espera
  83. encontrar el valor a guardar inmediatamente después de lo que constituye el
  84. verdadero 'opcode' (o código de operación), que es el que identifica a la ins-
  85. trucción y no depende del valor a guardar. Por eso, las primeras instrucciones
  86. (MOV AX,BX; etc...) sólo ocupan dos bytes (ambos forman el código de operación
  87. de la instrucción), mientras que las otras (MOV AX,1; etc...) ocupan dos o tres
  88. bytes. ¿A qué se debe esta diferencia del tamaño? Se debe a una característica
  89. del 8086 de la que todavía no hemos hablado:
  90.  
  91.    Cuando se diseñó el 8086, se penso (hicieron bien) que en algunos casos
  92. interesaría acceder por separado al byte alto y byte bajo que componen los
  93. registros, de manera que podamos operar con valores del tamaño de un byte. Por
  94. tanto, se incluyeron instrucciones que en lugar de operar sobre los registros
  95. de 16 bits completos operaban sobre los bytes que los componen. Esta subdivi-
  96. sión sólo se hizo para los cuatro registros de propósito general, y en ASM se
  97. identifican con los siguientes nombres:
  98.  
  99.     AX    ->    AH (byte alto) y AL (byte bajo)
  100.     BX    ->    BH ( "    "  ) y BL ( "    "  )
  101.     CX    ->    CH ( "    "  ) y CL ( "    "  )
  102.     DX    ->    DH ( "    "  ) y DL ( "    "  )
  103.  
  104.    Así, las siguientes instrucciones también tienen su correspondiente
  105. código de operación. Espero que su función resulte obvia:
  106.  
  107.         MOV AL,BL
  108.         MOV CH,CL
  109.         MOV DL,5
  110.         MOV BH,2
  111.  
  112.    Es necesario dejar claro que los registros AL y AH, por ejemplo, son parte
  113. del propio AX y por tanto no son independientes de éste. Por tanto, tras
  114. ejecutar las siguientes instrucciones:
  115.  
  116.         MOV AX,0FFFFh
  117.         MOV AL,00
  118.         MOV AH,00
  119.  
  120.    El registro AX valdrá 0000, ya que tanto su byte alto como su byte bajo se
  121. han puesto a cero.
  122.  
  123.    El tamaño de la instrucción 'MOV reg,valor', volviendo a donde lo dejamos,
  124. depende del tamaño del registro que se modifique. Si se modifica un registro de
  125. 16 bits, el dato que viene a continuación debe ser de éste tamaño, por lo que
  126. además del byte con el opcode necesitamos otros dos con el valor, por lo que el
  127. total es de tres bytes. En cambio, en una instrucción como 'MOV AL,00' sólo es
  128. necesario un byte con el valor después del opcode, por lo que el tamaño total
  129. de la instrucción es de dos bytes.
  130.  
  131.    Otro de los posibles usos de la instrucción MOV es el de cargar un registro
  132. con el contenido de una posición de memoria. El operando destino indicará el
  133. registro en el que se debe almacenar el valo, mientras que el operando origen
  134. será la dirección de la que se debe cargar el dato. Para indicar que lo que se
  135. quiere cargar es el valor contenido en la posición de memoria dada, se encierra
  136. la dirección entre corchetes:
  137.  
  138.         MOV AL,[0000]    ; Carga el valor de la posición cero en AL,
  139.                 ; a diferencia de la siguiente instrucción,
  140.         MOV AH,00    ; que carga el VALOR 0 en AH
  141.  
  142.    Ya que con los 16 bits que damos como dirección de memoria (no se pueden
  143. dar los 20 bits completos) no se puede generar la dirección completa, se usa
  144. el registro DS para formarla como vimos en el capítulo anterior. Más adelante
  145. veremos cómo se puede especificar que se use otro registro.
  146.  
  147.    Esto se denomina 'direccionamiento indirecto', en el que el operando es una
  148. posición de memoria de la que cargar el dato en lugar del valor a cargar. A
  149. proposito, el dar directamente el valor se denomina 'direccionamiento
  150. inmediato'.
  151.  
  152.    Si el registro indicado es de 16 bits, se carga el byte bajo de la dirección
  153. dada y el byte alto de la siguiente (ordenamiento Intel, ¿recordáis?).
  154.  
  155.         MOV AX,[0000]    ; Carga el valor de la posición 0 en AL
  156.                 ; y el de la posición 1 en AH
  157.  
  158.    Al igual que se puede cargar un registro con el contenido de una posición
  159. de memoria, se puede almacenar el contenido de un registro en una posición de
  160. memoria. La instrucción, como habréis adivinado, queda así:
  161.  
  162.         MOV [0000],AX    ; Almacena AL en la pos. 0 y AH en la pos. 1
  163.         MOV [0505h],AL    ; Almacena AL en la pos 0505h
  164.  
  165.    Aunque así podemos acceder a posiciones de memoria determinadas, a menudo
  166. interesa acceder a la posición de memoria indicada por un registro. En el caso
  167. del 8086, es posible acceder a la posición de memoria apuntada por BX, tanto
  168. para lectura como para escritura, de esta forma:
  169.  
  170.         MOV AL,[BX]    ; Carga en AL el valor almacenado en la
  171.                 ; posición de memoria dada por BX
  172.         MOV [BX],DX    ; Almacena DL en la posición dada por BX,
  173.                 ; y DH en la posición siguiente
  174.  
  175.    Para darnos más posibilidades, los códigos de operación del 8086 incluyen
  176. un acceso a memoria a una posición nn bytes más adelante de la dada por BX,
  177. todo en una sola instrucción:
  178.  
  179.         MOV AX,[BX+15d]    ; Carga los dos bytes de la posición apuntada
  180.                 ; por BX más 15 y de la siguiente
  181.         MOV [BX-12d],DL    ; Almacena DL en la dirección dada por BX
  182.                 ; menos 12
  183.  
  184.    Este valor que se suma a BX antes de generar el acceso a memoria viene, de
  185. la misma manera que el valor en el direccionamiento inmediato, inmediatamente
  186. después del código de operación, y forma parte de la instrucción. Si el valor
  187. del desplazamiento está entre -128d y +127d, es decir, 'cabe' en un byte
  188. (ya que el desplazamiento se interpreta como entero con signo), se genera una
  189. instrucción un byte más corta que si el valor necesita una palabra entera. De
  190. todas formas, el desplazamiento (el valor que se suma a BX) nunca puede salirse
  191. de una palabra.
  192.  
  193.    Hemos visto que el acceso a memoria por medio de un registro lo hacemos
  194. siempre con el BX. De hecho, no existen códigos de operación para acceder con
  195. el AX, el CX y el DX. Por tanto las siguientes instrucciones no las acceptará
  196. el ensamblador:
  197.  
  198.         MOV BX,[AX]    ; MAL
  199.         MOV CL,[DX]    ; MAL
  200.  
  201.    Y ahora, viendo esta limitación de registros para apuntar a memoria, llega
  202. el momento de introducir otros dos registros: el SI ('Source Index') y el DI
  203. ('Destination Index'). Estos registros admiten todos los modos de direcciona-
  204. miento que hemos visto, y además algunos que todavía no conocemos. La única
  205. diferencia es que no se puede acceder por separado a los bytes alto y bajo, por
  206. lo que siempre usaremos los registros 'enteros'.
  207.  
  208.    Por ejemplo, podemos hacer cosas como:
  209.  
  210.         MOV AX,0040h
  211.         MOV DS,AX    ; Segmento de datos a partir de 00400h absoluta
  212.         MOV SI,2
  213.         MOV AX,[SI]    ; Carga el byte almacenado en 00402h absoluta
  214.                 ; en AL, y el de 00403h en AH
  215.  
  216.    Bueno, en el siguiente capítulo seguiremos con más usos de la instrucción
  217. MOV (más modos de direccionamiento) y veremos cómo experimentar con el DEBUG.
  218. Pensaba explicar todo esto en un sólo capítulo, pero se me alarga demasié.
  219.  
  220.    Salut!!! :-)
  221.  
  222.    Jon